/* ***** BEGIN LICENSE BLOCK *****
 *   Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 * 
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is Blog Scrobbler.
 *
 * The Initial Developer of the Original Code is
 * Stan James.
 * Portions created by the Initial Developer are Copyright (C) 2009
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 * 
 * ***** END LICENSE BLOCK ***** */

var blogscrobbler = {

  // Our timer which we use to track how long page has been viewed
  viewTimer : null,
 
  // Details on the page currently being viewed by the user
  currentUrl : '',
  currentUrlShortened : '',
  currentTitle : '',
 
  // Record of URL's we've already scrobbled in this session.
  // We use an associatve array, so the URL is stored as the *key*
  scrobbledUrls : [],
  
  /**
   * Extension has just loaded
   */
  onLoad: function() {

    // initialization code
    this.initialized = true;
    this.strings = document.getElementById("blogscrobbler-strings");
    

/*    
    var prefs = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch);
    if (!prefs.getCharPref("extensions.blogscrobbler.twitterUsername")) {
      var promptService = Components.classes["@mozilla.org/embedcomp/prompt-service;1"].getService(Components.interfaces.nsIPromptService);      
      var username = {value: ""};              // default the username to user
      var password = {value: ""};              // default the password to pass
      var check = {value: true};                   // default the checkbox to true
      var result = promptService.promptUsernameAndPassword(null, "Title", "Enter username and password for your scrobbling twitter account:\n(This should NOT be your usual twitter account.)", username, password, "Save", check);
      alert(password.value);
      // result is true if OK was pressed, false if cancel was pressed. username.value,
      // password.value, and check.value are set if OK was pressed.
    }
*/

    // add page change listener (this even fires first, when the user first navigates to a new page)
    window.getBrowser().addProgressListener(blogscrobblerListener, Components.interfaces.nsIWebProgress.NOTIFY_STATE_DOCUMENT);
    
    // add page load listener (this fires after the DOM of the page has loaded)
    document.getElementById("content").addEventListener("DOMContentLoaded", blogscrobbler.potentialScrobble, true);
  },

  /**
   *
   */
  windowUnload: function() {
    window.getBrowser().removeProgressListener(blogscrobblerListener);
    document.getElementById("content").removeEventListener("DOMContentLoaded", blogscrobbler.potentialScrobble, true);
  },
  
  /**
   *
   */
  addBlacklist: function(e) {
    var uri = Components.classes['@mozilla.org/network/standard-url;1'].createInstance(Components.interfaces.nsIURI);
    uri.spec = this.currentUrl;
    var domain = uri.host.replace(/^www\./i,"");    
    var specials = new RegExp("[.*+?|()\\[\\]{}\\\\]", "g"); // .*+?|()[]{}\
    regExpDomain = domain.replace(specials, "\\$&");        
    var prefs = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch);
    prefs.setCharPref("extensions.blogscrobbler.blacklist", regExpDomain + "\n" + prefs.getCharPref("extensions.blogscrobbler.blacklist"));
    alert("Future visits to " + domain + " will not be recorded.\n\nYou can modify your list of blacklisted domains at any time\n by selecting \"Blog Scrobbler Options\" from the Tools menu.");    
  },

  /**
   *
   */
  addWhitelist: function(e) {
    var uri = Components.classes['@mozilla.org/network/standard-url;1'].createInstance(Components.interfaces.nsIURI);
    uri.spec = this.currentUrl;
    var domain = uri.host.replace(/^www\./i,"");    
    var specials = new RegExp("[.*+?|()\\[\\]{}\\\\]", "g"); // .*+?|()[]{}\
    regExpDomain = domain.replace(specials, "\\$&");        
    var prefs = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch);
    prefs.setCharPref("extensions.blogscrobbler.whitelist", regExpDomain + "\n" + prefs.getCharPref("extensions.blogscrobbler.whitelist"));
    alert("Future visits to " + domain + " will always be recorded.\n\nYou can modify your list of whitelisted domains at any time\n by selecting \"Blog Scrobbler Options\" from the Tools menu.");    
  },
  
  /**
   *
   */
  onToolbarButtonCommand: function(e) {
    // just reuse the function above.  you can change this, obviously!
    blogscrobbler.onMenuItemCommand(e);
  },
  
  /**
   * Called whenever a page loads in browser 
   * At this point we can get the title of the page, and since
   * the page is actually showing, we can start our timer.
   */  
  potentialScrobble: function(e) {

    var prefs = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch);
		
    // If first run
    if (prefs.getBoolPref("extensions.blogscrobbler.firstTime")) {
/*
      // send it to twitter api
      var twitterFollowUri = "http://twitter.com/notifications/follow/".twitterUsername.".json";
      var params = "id=blogscrobblers";
      var reghttp = new XMLHttpRequest();
      reghttp.open("POST", twitterFollowUri, true, twitterUsername, twitterPassword);
      reghttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
      reghttp.setRequestHeader("Content-Length", params.length); 
      reghttp.setRequestHeader("Connection", "close");    
      reghttp.onreadystatechange = function() { 
        if ((reghttp.readyState == 4) && (reghttp.status == 200)) {
          var response = eval('('+reghttp.responseText+ ')');
          prompt("Registered:",reghttp.responseText);
        }
      };
      reghttp.send(params);
*/      
			loadURI("http://code.google.com/p/blogscrobbler/wiki/JustInstalled");
      prefs.setBoolPref("extensions.blogscrobbler.firstTime", false);
			
    }
				
		
    // First confirm that the page that just loaded is the same URL
    // that is showing in the location bar. (DOMLoaded will also fire
    // for the loading of iframes and such.)
    if (e.target.URL != blogscrobbler.currentUrl) {
      return;      
    }
    // Record title of this page
    blogscrobbler.currentTitle = e.target.title;

    // Strip off any hash referencens in the URL
    // (So we don't count them as another view of the same post)
    // blogscrobbler.currentUrl = blogscrobbler.currentUrl.replace(/#.*/,''); 
    
    // Clear any existing timer.
    clearTimeout(blogscrobbler.viewTimer);

    if (blogscrobbler.scrobbledUrls[blogscrobbler.currentUrl]) {
      // Oops, we've already scrobbled this. Skip it
      return false;
    }
    
    if (!prefs.getBoolPref("extensions.blogscrobbler.doScrobble")) {
      return;
    }    
        
    if (blogscrobbler.isBlogUrl(blogscrobbler.currentUrl)) {      
    
      if (!prefs.getCharPref("extensions.blogscrobbler.twitterUsername")) {
        //blogscrobbler.showMessage("Blog scrobbling is not set up. Select 'Blog Scrobbler Options' from Tools menu.");        
				if (confirm("This looks like a blog post, but you have not yet configured Blog Scrobbler with your Twitter.\nWould you like to enter your Twitter information now?")) {
					window.openDialog('chrome://blogscrobbler/content/options.xul', 'Preferences', 'chrome,titlebar,toolbar,centerscreen');
				}
        return;
      }

      // It's a blog post!
      // Start timer
      var scrobbleTimeMilliseconds = 1000 * prefs.getIntPref("extensions.blogscrobbler.scrobbleTime");
      blogscrobbler.viewTimer = setTimeout("blogscrobbler.doScrobble()", scrobbleTimeMilliseconds);

      blogscrobbler.showMessage("Will scrobble in " + (scrobbleTimeMilliseconds/1000) + " seconds.");
    }
    else {
      // Not a blog post.
    }
    
  },

  showMessage: function(msg) {
    var oldMsg = content.document.getElementById('blogscrobbler-messagebox');
    if (oldMsg) {
      oldMsg.innerHTML = msg;
    }      
    else {
      var domMsg = "<div id='blogscrobbler-messagebox' style='font: arial; font-size:14px; padding: 3px; text-align: left; color: black; position:absolute; top: 5px; right:5px; background-color: yellow; width: 300px; height: 30px;' onclick='document.getElementById(\"blogscrobbler-messagebox\").style.display=\"none\"'>" + msg + "</div>\n"
      content.document.body.innerHTML += domMsg;    
    }
  },
  
  /**
   * Determine if URL is a blog post
   */
  isBlogUrl: function(url) {
  
    // load prefs
    var prefs = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch);
    var blacklistPatterns = prefs.getCharPref("extensions.blogscrobbler.blacklist").split("\n");
    var whitelistPatterns = prefs.getCharPref("extensions.blogscrobbler.whitelist").split("\n");        

    // see if url matches blacklist
    for (var i in blacklistPatterns) {
      if (!blacklistPatterns[i]) { 
        // pattern was empty
        continue; 
      }
      if (url.match(new RegExp(blacklistPatterns[i]))) {
        // regexp match
        return false;
      }
    }
    
/*    
    // see who generator is
    for (var i in content.document.getElementsByTagName("meta")) {
      if (content.document.getElementsByTagName("meta")[i].name == "generator") {
        // see if it's a blogging platform
        var generator = ""+content.document.getElementsByTagName("meta")[i].content;
        alert(generator);
        if (generator.match(/Wordpress/)) {
          return true;
        }
        if (generator.match(/typepad/)) {
          return true;
        }
      }
    }        
*/

    // see if url matches whitelist
    for (var i in whitelistPatterns) {
      if (!whitelistPatterns[i]) { 
        // pattern was empty
        continue; 
      }
      if (url.match(new RegExp(whitelistPatterns[i]))) {
        // regexp match
        return true;
      }
    }    
    
    // if on neither list, then default to it not being a blog
    return false;
  },
  
  /**
   * Scrobble a URL -- send it to Twitter
   */
  doScrobble: function() {
        
    if ((blogscrobbler.currentUrl.length > 140) || (Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch).getBoolPref("extensions.blogscrobbler.alwaysShortenUrls"))) {
      // shorten the URL
      
      var prefs = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch);
      var bitlyUsername   = prefs.getCharPref("extensions.blogscrobbler.bitlyUsername");                    
      var bitlyApiKey     = prefs.getCharPref("extensions.blogscrobbler.bitlyApiKey");                
      if (bitlyUsername && bitlyApiKey) {
        // bit.ly
        var xmlhttp = new XMLHttpRequest();
        xmlhttp.open("GET", "http://api.bit.ly/shorten?version=2.0.1&longUrl=" + encodeURIComponent(blogscrobbler.currentUrl) + "&login=" + encodeURIComponent(bitlyUsername) + "&apiKey=" + bitlyApiKey);
        
        xmlhttp.onload = function() { 
          var responseJson = eval("(" + xmlhttp.responseText + ")");
          blogscrobbler.currentUrlShortened = responseJson.results[blogscrobbler.currentUrl].shortUrl;
          blogscrobbler.doScrobble2();
        }
        xmlhttp.onerror = function() {
          blogscrobbler.currentUrlShortened = "";
          blogscrobbler.doScrobble2();
        }
        xmlhttp.send(null);            
      }
      else {
        // tinyurl.com
        var xmlhttp = new XMLHttpRequest();
        xmlhttp.open("GET", "http://tinyurl.com/api-create.php?url=" + encodeURIComponent(blogscrobbler.currentUrl))
        xmlhttp.onload = function() { 
          blogscrobbler.currentUrlShortened = (xmlhttp.responseText);
          blogscrobbler.doScrobble2();
        }
        xmlhttp.onerror = function() {
          blogscrobbler.currentUrlShortened = "";
          blogscrobbler.doScrobble2();
        }
        xmlhttp.send(null);    
      }
    }
    else {
      // Don't shorten URL
      blogscrobbler.currentUrlShortened = "";
      blogscrobbler.doScrobble2();
    }
    
  },
  
  doScrobble2: function() {
    // load credentials 
    var prefs = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch);
    var twitterUsername = prefs.getCharPref("extensions.blogscrobbler.twitterUsername");                        
    var twitterPassword = prefs.getCharPref("extensions.blogscrobbler.twitterPassword");                        




    // assemble our tweet
    // twitter will cut it off if it's too long
    var tweet = (blogscrobbler.currentUrlShortened ? blogscrobbler.currentUrlShortened : this.currentUrl) + " " + this.currentTitle;

    // record that we've seen this url
    blogscrobbler.scrobbledUrls[this.currentUrl] = true;
    
    if (!prefs.getBoolPref("extensions.blogscrobbler.doScrobble")) {
      //blogscrobbler.showMessage('Scrobbling disabled: Would have scrobbled:\n' + tweet);
      return;
    }
        
    // send it to twitter api
    // see: http://www.xulplanet.com/references/objref/XMLHttpRequest.html
    // see: http://www.openjs.com/articles/ajax_xmlhttp_using_post.php
    var twitterPostUri = "http://twitter.com/statuses/update.json";
    var params = "status=" + encodeURIComponent(tweet);
    var xmlhttp = new XMLHttpRequest();
    xmlhttp.open("POST", twitterPostUri, true, twitterUsername, twitterPassword);
    xmlhttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
    xmlhttp.setRequestHeader("Content-Length", params.length); 
    xmlhttp.setRequestHeader("Connection", "close");    
    xmlhttp.onreadystatechange = function() { 
      if ((xmlhttp.readyState == 4) && (xmlhttp.status == 200)) {
        var response = eval('('+xmlhttp.responseText+ ')');
        var postUrl = 'http://twitter.com/' + response.user.screen_name + '/status/' + response.id
        blogscrobbler.showMessage('<a href="' + postUrl + '">Scrobbled this post.</a>');
      }
    };
    xmlhttp.send(params);
        
  },
 
  /**
   * https://developer.mozilla.org/en/nsIConsoleService
   */
  LOG: function (msg) {
    //var consoleService = Components.classes["@mozilla.org/consoleservice;1"]
    //                               .getService(Components.interfaces.nsIConsoleService);
    //consoleService.logStringMessage(msg);
    Components.utils.reportError(msg);
  }
  
};
window.addEventListener("load", function(e) { blogscrobbler.onLoad(e); }, false);
window.addEventListener("unload", function(e) { blogscrobbler.windowUnload(e); }, false);

//////////////////////////////////////////////////////////////////
// Web Page Listeners (fired when user changes page viewed)

var blogscrobblerListener = {
  onLocationChange:function(webProgress, request, loc) {
    blogscrobbler.currentUrl = loc.spec;
    blogscrobbler.currentTitle = "";
    blogscrobbler.currentUrlShortened = "";
    // don't mess with jar files or Firefox will crash
    if (blogscrobbler.currentUrl.slice(0,4) == "jar:") {
      blogscrobbler.currentUrl = ""; 
    }
  },
  QueryInterface : function(aIID) { // override nsISupports
    if (
      aIID.equals(Components.interfaces.nsIObserver) ||
      aIID.equals(Components.interfaces.nsIWebProgressListener) ||
      aIID.equals(Components.interfaces.nsIProgressEventSink) ||
      aIID.equals(Components.interfaces.nsIHttpEventSink) ||
      aIID.equals(Components.interfaces.nsIRequestObserver) ||
      aIID.equals(Components.interfaces.nsISupportsWeakReference) ||
      aIID.equals(Components.interfaces.nsISupports) ||
      aIID.equals(Components.interfaces.nsIWebProgress))
    {
      return this;
    }
    throw Components.results.NS_NOINTERFACE;
  },
  onStateChange:function(aProgress, aRequest, aFlags, aStatus) { },
  onProgressChange:function(webProgress, request, curSelfProgress, maxSelfProgress, curTotalProgress, maxTotalProgress) { },
  onStatusChange:function(aProgress, aRequest, aStatus, aMessage) { },
  onSecurityChange:function(webProgress, request, state) { },
  // This is not nsIWebProgressListenr method,
  // just killing a error in tabbrowser.xml
  // Maybe a bug.
  onLinkIconAvailable:function(a)   { }
};

